package com.lwl.concurrency.executor;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**<pre>
 *  线程池ThreadPoolExecutor,jdk提供了4种内置的拒绝策略
 *  AbortPolicy策略:该策略会直接抛出异常,阻止系统正常工作
 *  CallerRunsPolicy策略:只要线程池没有关闭,该策略直接在调用者线程中执行被丢弃的任务,
 *  会导致任务提交线程性能急剧下降
 *  DiscardOledestPolicy策略:该策略丢弃任务队列中最老的一个任务,并立即执行最新的任务
 *  DiscardPolicy策略:丢弃最新提交的任务
 *  可以自定策略:例如将任务放在rabbitMq中,平缓的执行
 * </pre>
 * Created by liwenlong on 2018/1/11 16:37
 */
public class RejectedExecutionHandlerTest {

    /**
     * 创建RejectedTaskController类，实现RejectedExecutionHandler接口。<br>
     * 写入被拒绝任务的名称和执行者的名称与状态到控制台
     */
    public static class RejectedTaskController implements RejectedExecutionHandler{
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            System.out.println("可以将任务放到消息中间件rabbitmq");
        }
    }

    public static class Task implements Runnable{
        private String name;

        public Task(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+" "+name+": Starting");
            try {
                long duration=(long)(Math.random()*10);
                System.out.printf("Task %s: ReportGenerator: Generating a report during %d seconds\n",name,duration);
                TimeUnit.SECONDS.sleep(duration);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.printf(Thread.currentThread().getName()+" %s: Ending\n",name);
        }
        @Override
        public String toString() {
            return name;
        }
    }


    public static void main(String[] args) {
        RejectedTaskController controller = new RejectedTaskController();
        //ThreadPoolExecutor executor = (ThreadPoolExecutor)Executors.newFixedThreadPool(3);

        int nThreads = 3;
        ThreadPoolExecutor executor =  new ThreadPoolExecutor(nThreads, nThreads,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>(5));
        //建立执行者的拒绝任务控制器
        executor.setRejectedExecutionHandler(controller);

        System.out.println("Main: Staring");
        for (int i = 0; i <10 ; i++) {
            Task task = new Task("Task-"+i);
            executor.submit(task);
        }
        System.out.println("Main: Shutting down the Executor");
        executor.shutdown();
        System.out.println("Main: Sending another Task.");
        Task task = new Task("RejectedTask....");
        executor.submit(task);
        System.out.println("Main:end");

    }


}
